package com.origin.utils.permissions;

import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PermissionsAndActivityResultFragment extends Fragment {

    /**
     * 请求的权限组
     */
    private static final String REQUEST_PERMISSIONS = "request_permissions";

    /**
     * 请求码（自动生成）
     */
    private static final String REQUEST_CODE = "request_code";
    /**
     * 权限请求码存放集合
     */
    private static final List<Integer> REQUEST_CODE_ARRAY = new ArrayList<>();

    private static int makeRequestCode() {
        int requestCode;
        // 请求码随机生成，避免随机产生之前的请求码，必须进行循环判断
        do {
            // 新版本的 Support 库限制请求码必须小于 65536
            // 旧版本的 Support 库限制请求码必须小于 256
            requestCode = new Random().nextInt((int) Math.pow(2, 8));
        } while (REQUEST_CODE_ARRAY.contains(requestCode));
        return requestCode;
    }

    /**
     * 权限申请标记
     */
    private boolean mRequestFlag;

    /**
     * 开启权限申请
     */
    public static PermissionsAndActivityResultFragment permission(FragmentActivity activity, ArrayList<String> permissions) {
        PermissionsAndActivityResultFragment permissionsAndActivityResultFragment = new PermissionsAndActivityResultFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(REQUEST_CODE, makeRequestCode());
        bundle.putStringArrayList(REQUEST_PERMISSIONS, permissions);
        permissionsAndActivityResultFragment.setArguments(bundle);
        // 设置保留实例，不会因为屏幕方向或配置变化而重新创建
        permissionsAndActivityResultFragment.setRetainInstance(true);
        // 设置权限申请标记
        permissionsAndActivityResultFragment.setRequestFlag(true);
        // 设置权限回调监听
//        permissionsAndActivityResultFragment.setCallBack(onPermissionPageCallback);
        // 绑定到 Activity 上面
        permissionsAndActivityResultFragment.attachActivity(activity);

        return permissionsAndActivityResultFragment;

    }

    public static PermissionsAndActivityResultFragment forResult(FragmentActivity activity) {
        PermissionsAndActivityResultFragment permissionsAndActivityResultFragment = new PermissionsAndActivityResultFragment();
        // 设置保留实例，不会因为屏幕方向或配置变化而重新创建
        permissionsAndActivityResultFragment.setRetainInstance(true);
        // 设置权限申请标记
        permissionsAndActivityResultFragment.setRequestFlag(true);
        // 设置权限回调监听
//        permissionsAndActivityResultFragment.setCallBack(onPermissionPageCallback);
        // 绑定到 Activity 上面
        permissionsAndActivityResultFragment.attachActivity(activity);

        return permissionsAndActivityResultFragment;
    }

    int _requestCode = -1;

    public PermissionsAndActivityResultFragment setRequestCode(int requestCode) {
        _requestCode = requestCode;
        return this;
    }

    OnPermissionPageCallback _onPermissionPageCallback;
    OnActivityResultCallback _onActivityResultCallback;


    /**
     * 绑定 Activity
     */
    public void attachActivity(FragmentActivity appCompatActivity) {
        appCompatActivity.getSupportFragmentManager().beginTransaction().add(this, this.toString()).commitNow();
    }

    /**
     * 解绑 Activity
     */
    public void detachActivity(FragmentActivity appCompatActivity) {
        appCompatActivity.getSupportFragmentManager().beginTransaction().remove(this).commitNow();
    }

    /**
     * 权限申请标记（防止系统杀死应用后重新触发请求的问题）
     */
    public void setRequestFlag(boolean flag) {
        mRequestFlag = flag;
    }

    @Override
    public void onResume() {
        super.onResume();
        // 如果当前 Fragment 是通过系统重启应用触发的，则不进行权限申请
        if (!mRequestFlag) {
            if (getActivity() != null) {
                detachActivity(getActivity());
            }
            return;
        }
    }

    public void requestPermissions(OnPermissionPageCallback callback) {
        Activity activity = getActivity();
        Bundle arguments = getArguments();

        if (arguments == null || activity == null) {
            return;
        }

        final int requestCode = arguments.getInt(REQUEST_CODE);

        final ArrayList<String> allPermissions = arguments.getStringArrayList(REQUEST_PERMISSIONS);
        _onPermissionPageCallback = callback;
        if (PermissionsUtils.INSTANCE.checkPermissions(activity, allPermissions.toArray(new String[0]))) {
            _onPermissionPageCallback.onGranted(allPermissions);
            return;
        }
        requestPermissions(allPermissions.toArray(new String[0]), requestCode);
    }

    private boolean isPermissionsRequestSetting;

    private void toSettingsPage(Activity activity) {
        AlertDialog alertDialog = new AlertDialog.Builder(activity)
                .setTitle("权限设置")
                .setMessage("应用缺乏必要的权限，是否前往手动授予该权限？")
                .setPositiveButton("前往", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        toSettingsPageAction(activity);
                    }
                })
                .setNegativeButton("取消", null)
                .create();
        alertDialog.show();
    }

    // 去设置页面行为
    public void toSettingsPageAction(Activity activity) {
        isPermissionsRequestSetting = true;
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, 3333);
    }

    public void startActivityForResult(Intent intent, OnActivityResultCallback onActivityResultCallback) {
        _onActivityResultCallback = onActivityResultCallback;
        if (_requestCode == -1) {
            startActivityForResult(intent, makeRequestCode());
        } else {
            startActivityForResult(intent, _requestCode);
        }

    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        FragmentActivity activity = getActivity();
        Bundle arguments = getArguments();
        if (activity == null || arguments == null || _onPermissionPageCallback == null ||
                requestCode != arguments.getInt(REQUEST_CODE)) {
            return;
        }
        // 释放对这个请求码的占用
        REQUEST_CODE_ARRAY.remove((Integer) requestCode);
        final ArrayList<String> allPermissions = arguments.getStringArrayList(REQUEST_PERMISSIONS);
        // 获取已授予的权限
        List<String> grantedPermissions = getGrantedPermissions(allPermissions, grantResults);
        // 获取被拒绝的权限
        List<String> deniedPermissions = getDeniedPermissions(allPermissions, grantResults);
        if (grantedPermissions.size() == allPermissions.size()) {
            Log.e("====", "size " + grantedPermissions.size());
            _onPermissionPageCallback.onGranted(grantedPermissions);
        }
        if (deniedPermissions.size() > 0) {
            if (PermissionsUtils.INSTANCE.isDeclinedAndNotAsked(activity, deniedPermissions)) {
                toSettingsPage(activity);
                return;
            }
            //检查是否拒绝且不在询问
            _onPermissionPageCallback.onDenied(deniedPermissions);
        }
        detachActivity(activity);

    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (_onActivityResultCallback != null) {
            _onActivityResultCallback.onActivityResult(requestCode, resultCode, data);
        }

        // 跳转到设置页后权限检查
        if (isPermissionsRequestSetting) {
            FragmentActivity activity = getActivity();
            Bundle arguments = getArguments();
            if (activity == null || arguments == null || _onPermissionPageCallback == null ||
                    requestCode != 3333) {
                return;
            }
            // 释放对这个请求码的占用
            REQUEST_CODE_ARRAY.remove((Integer) requestCode);
            detachActivity(activity);
            final ArrayList<String> allPermissions = arguments.getStringArrayList(REQUEST_PERMISSIONS);
            // 获取已授予的权限
            List<String> grantedPermissions = PermissionsUtils.INSTANCE.getGrantedPermissions(activity, allPermissions);
            // 获取被拒绝的权限
            List<String> deniedPermissions = PermissionsUtils.INSTANCE.getDeniedPermissions(activity, allPermissions);
            if (grantedPermissions.size() > 0) {
                _onPermissionPageCallback.onGranted(grantedPermissions);
            }
            if (deniedPermissions.size() > 0) {
                _onPermissionPageCallback.onDenied(deniedPermissions);
            }
            isPermissionsRequestSetting = false;
        }
    }

    /**
     * 获取没有授予的权限
     *
     * @param permissions  需要请求的权限组
     * @param grantResults 允许结果组
     */
    static List<String> getDeniedPermissions(List<String> permissions, int[] grantResults) {
        List<String> deniedPermissions = new ArrayList<>();
        for (int i = 0; i < grantResults.length; i++) {
            // 把没有授予过的权限加入到集合中
            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                deniedPermissions.add(permissions.get(i));
            }
        }
        return deniedPermissions;
    }

    /**
     * 获取已授予的权限
     *
     * @param permissions  需要请求的权限组
     * @param grantResults 允许结果组
     */
    static List<String> getGrantedPermissions(List<String> permissions, int[] grantResults) {
        List<String> grantedPermissions = new ArrayList<>();
        for (int i = 0; i < grantResults.length; i++) {
            // 把授予过的权限加入到集合中
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                grantedPermissions.add(permissions.get(i));
            }
        }
        return grantedPermissions;
    }
}
